using System;
using System.Collections.Generic;
using System.IO;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Data.Measurement;
using FilteredStatistics.Common.Controller;
using FilteredStatistics.View;

namespace FilteredStatistics.Data
{
    class RemoveDescentRangeSectionsPostProcessFilter : IPostProcessFilter
    {
        public RemoveDescentRangeSectionsPostProcessFilter(Stream stream, DataVersion version)
        {
            Deserialize(stream, version);
        }

        public RemoveDescentRangeSectionsPostProcessFilter(float minRange, float maxRange, Length.Units unit)
        {
            m_MinRangeDescent = Math.Min(minRange, maxRange);
            m_MaxRangeDescent = Math.Max(minRange, maxRange);
            m_ElevationUnit = unit;
        }

#region IPostProcessFilter Members

        public override PostProcessType Type
        {
            get { return PostProcessType.RemoveDescentRange; }
        }

        public override String DisplayString
        {
            get
            {
                return String.Format(PluginView.GetLocalizedString("RemoveDescentRangePPText"),
                                     m_MinRangeDescent, m_MaxRangeDescent, Length.LabelAbbr(m_ElevationUnit));
            }
        }

        public override List<ActivityRangeInfoCache> FilterResults(IList<ActivityRangeInfoCache> rangesToFilter, IActivity activity)
        {
            List<ActivityRangeInfoCache> result = new List<ActivityRangeInfoCache>();

            foreach (ActivityRangeInfoCache range in rangesToFilter)
            {
                double totalDescent = Length.Convert(FilteredStatisticsStatisticsProvider.Instance.GetTotalDescentValue(range), activity.Category.ElevationUnits, m_ElevationUnit);

                if (totalDescent < m_MinRangeDescent ||
                    totalDescent > m_MaxRangeDescent)
                {
                    result.Add(range);
                }
            }

            return result;
        }

        public override int CompareTo(IPostProcessFilter filter)
        {
            if (filter is RemoveAscentRangeSectionsPostProcessFilter ||
                filter is RemoveDescentRangeSectionsPostProcessFilter)
            {
                return 0;
            }

            return 1;
        }

#endregion

#region IPluginSerializable members

        public override void Serialize(Stream stream)
        {
            base.Serialize(stream);

            SerializableDoubleRange minRange = new SerializableDoubleRange(m_MinRangeDescent);
            SerializableDoubleRange maxRange = new SerializableDoubleRange(m_MaxRangeDescent);
            SerializableUInt16Range unit = new SerializableUInt16Range((UInt16)m_ElevationUnit);

            minRange.Serialize(stream);
            maxRange.Serialize(stream);
            unit.Serialize(stream);
        }

#endregion

        #region Deserialization methods

        public override void Deserialize_V2(Stream stream, DataVersion version)
        {
            SerializableDoubleRange minRange = new SerializableDoubleRange(0);
            SerializableDoubleRange maxRange = new SerializableDoubleRange(0);
            SerializableUInt16Range unit = new SerializableUInt16Range(0);

            minRange.Deserialize(stream, version);
            maxRange.Deserialize(stream, version);
            unit.Deserialize(stream, version);

            m_MinRangeDescent = (float)minRange;
            m_MaxRangeDescent = (float)maxRange;
            m_ElevationUnit = (Length.Units)(int)unit;
        }

        #endregion

        public float RangeMinDescent
        {
            get { return m_MinRangeDescent; }
        }

        public float RangeMaxDescent
        {
            get { return m_MaxRangeDescent; }
        }

        public Length.Units ElevationUnit
        {
            get { return m_ElevationUnit; }
        }

        private float m_MinRangeDescent;
        private float m_MaxRangeDescent;
        private Length.Units m_ElevationUnit;
    }
}
